import numpy as np
from sklearn.linear_model import LogisticRegression  # 用现成的库进行对比试验
from sklearn.preprocessing import StandardScaler
from sklearn import datasets

#第一步得到样本
def get_data():
    digits = datasets.load_digits()
    x, y = digits.data, digits.target
    x = StandardScaler().fit_transform(x)#64
    y = (y > 4).astype(np.int)  # 将大于4和小于4的数字分两组并二值化
    #print(len(y))  1797
    return x,y

def sigmoid(x):
    return 1.0/(1+np.exp(-x))

def logistic1():
    data,label = get_data()
    data = np.mat(data) #(1797,64)
    label = np.mat(label).transpose()  #(1797,1)
    m,n = np.shape(data)
    #初次定义权重
    weights = np.ones((n,1))
    #初次定义学习率
    learning_rate = 0.001
    #定义训练轮数
    epoch = 500
    #开始学习
    for i in range(epoch):
        e = sigmoid(data * weights)  #(1797,64) * (64,1) = (1797,1)
        error = (label - e)    #(1797,1)
        weights = weights + learning_rate * data.transpose() * error
    return weights.shape

def logistic2():
    data, label = get_data()
    m,n = data.shape
    # 初次定义权重
    weights = np.ones(n)
    # 初次定义学习率
    learning_rate = 0.001
    for i in range(m):
        e = sigmoid(sum(data[i] * weights))
        error = label[i] - e
        weights = weights + learning_rate * data[i] * error
    return weights

def logistic3():
    data, label = get_data()
    m,n = data.shape
    # 初次定义权重
    weights = np.ones(n)
    #迭代次数
    epoch = 500
    for i in range(epoch):
        data1 = data
        for j in range(m):
            learning_rate = 4/(1+i+j)+0.001  #学习率不断在变化，但是不会为0
            rand = int(np.random.uniform(0,len(data1))) #随机训练
            e = sigmoid(sum(data1[rand] * weights))
            error = label[rand] - e
            weights = weights + learning_rate * data1[rand] * error
            data1 = np.delete(data1, rand,axis = 0)#每次训练完，删除训练的样本
    return weights


def logistic4():
    data, label = get_data()
    LR = LogisticRegression(C=0.1, penalty='l2', tol=0.01)
    LR.fit(data, label)
    predict = LR.predict(data)
    print((predict == label).astype(np.int).mean())


if __name__ == "__main__":
    logistic4()

